package com.cht.commonUtil.deployment;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jboss.as.cli.CommandContext;
import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.dmr.ModelNode;
import org.tmatesoft.svn.core.SVNProperties;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNWCUtil;

import com.cht.commonUtil.webInit.SP;
import com.cht.commonUtil.enums.MailType;
import com.cht.commonUtil.enums.RecipientType;
import com.cht.commonUtil.widgets.Widgets;

public class Tester2Deploy extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request,response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		response.setCharacterEncoding( SP.UIcodeSet );
		response.setContentType("application/text");

		String[] aps = new String[4];
		int apType = 1;	//1代表測試人員
		
		String empId = request.getParameter("empId");	//執行部署的人員
		String squadId = "testEnvServerGroup";						//欲部署的SQUAD
		String subsysDesc = request.getParameter("subsysDesc");
		String empName = request.getParameter("empName");
		String committer = request.getParameter("committer");
		String cDT = request.getParameter("cDT");
		String[] fileArray = request.getParameter( "fileListStr" ).split( Widgets.splitTokenONE );
		int chkInId = Integer.parseInt( request.getParameter("chkInId") );
		
		
		ByteArrayOutputStream baos = null;
		SVNRepository repo = null;
		InputStream ins = null;
		OutputStream outputStream = null;
		CommandContext cmdCtx = null;
		ModelControllerClient client = null;
		ModelNode requestNode = null;
		ModelNode result = null;
		String res = "";
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		File fn = null;
		
		try {
			conn = Widgets.getConn();
			
			String sql = "SELECT t2.url,t2.id,t2.pwd,t2.path,t1.subsysId,t1.exeVer FROM chkinmain t1,svnExeRepos t2 WHERE t1.svnExeRepoSN=t2.svnExeRepoSN AND t1.chkInMainId=?";
			ps = conn.prepareStatement(sql);
			ps.setInt(1, chkInId);
			rs = ps.executeQuery();
			rs.next();
			String subsysId = rs.getString("subsysId");
			String svnURL = rs.getString("url");				//SVN CM OL 封裝區 的連線位址
			String svnUSR = rs.getString("id");				//SVN CM OL 封裝區 的登入帳號
			String svnPWD = rs.getString("pwd");				//SVN CM OL 封裝區 的登入密碼
			int exeVer = rs.getInt("exeVer");
			
			String fileList4Mail = "";
			for( int a=0; a<fileArray.length;a++ ) {
				fileList4Mail += "<li>"+fileArray[a]+"</li>";
			}
			
			String msgBody = "<font face='微軟正黑體'>您好,<p>"+subsysDesc+"的&nbsp;"+empName+"&nbsp;已部署封裝檔至 QA環境<p></font> ";	//信件內容
			msgBody += "相關資訊如下：<table>"+
					"<tr><td align='right'><font face='微軟正黑體'>繳交代號：</font></td><td align='left'><font face='Calibri'>"+chkInId+"</font></td></tr>"+
					"<tr><td align='right'><font face='微軟正黑體'>繳交人員：</font></td><td align='left'><font face='微軟正黑體'>"+committer+"</font></td></tr>"+
					"<tr><td align='right'><font face='微軟正黑體'>繳交時間：</font></td><td align='left'><font face='Calibri'>"+cDT+"</font></td></tr>"+
					"<tr><td align='right' valign='middle'><font face='微軟正黑體'>部署檔名：</font></td><td><font face='Calibri'><ul>"+fileList4Mail+"</ul></font></td></tr>"+
					"<tr><td align='right'><font face='微軟正黑體'>部署版次：</font></td><td align='left'><font face='Calibri'>"+exeVer+"</font></td></tr>"+
					"<tr><td align='right'><font face='微軟正黑體'>檔案來源：</font></td><td align='left'><font face='Calibri'>"+svnURL+"</font></td></tr>"+
					"</table><p><p>";
			if ( rs !=null ) {rs.close();}
			if ( ps !=null ) {ps.close();}
			
			String reqs = "<ul class='zhTwN req'>";
			sql = "SELECT t1.reqSID,t1.reqDesc FROM reqs t1,mpChkinReq t2 WHERE t1.reqId=t2.reqId AND t2.chkInMainId=?";
			ps = conn.prepareStatement(sql);
			ps.setInt(1, chkInId);
			rs = ps.executeQuery();
			while( rs.next() ) {
				reqs += "<li>"+rs.getString("reqSID")+"-"+rs.getString("reqDesc")+"</li>";
			}
			reqs += "</ul>";
			msgBody += "<font face='微軟正黑體'>相關需求："+reqs+"<p><p>Best regards<br>"+empName+"</font><p><p>";
			
			
			ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(svnUSR, svnPWD);
			List<String> file4Dep = new ArrayList<String>();
			sql = "SELECT modId FROM objectlist WHERE subsysId=? ORDER BY deployOrder DESC";
			ps = conn.prepareStatement(sql);
			ps.setString(1, subsysId );
			rs = ps.executeQuery();
			while( rs.next() ) {
				file4Dep.add( rs.getString("modId") );
			}
			
			//取得 AP Server的連線資訊
			aps = Widgets.getAP4SubsysConnInfo(subsysId, apType);
			String apIP = aps[0];							//連線IP
			int apPORT = Integer.parseInt( aps[1] );		//連線PORT
			String apUSR = aps[2];						//登入帳號
			char[] apPWD = aps[3].toCharArray();			//登入密碼
			
			repo = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(svnURL));
			repo.setAuthenticationManager(authManager);
			
			sql = "INSERT INTO depmemphis (svnUSR,svnURL,chkInId,cDT,creatorId) VALUES (?,?,?,?,?)";
			ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS );
			ps.setString(1, svnUSR);
			ps.setString(2, svnURL);
			ps.setInt(3, chkInId);
			ps.setTimestamp(4, Widgets.cDT());
			ps.setString(5, empId);
			ps.executeUpdate();
			rs = ps.getGeneratedKeys();
			rs.next();
			int depMemphisSN = rs.getInt(1);
			
			//先進行下線，再進行部署
			
			cmdCtx = Widgets.initCommandContext(apIP, apPORT, apUSR, apPWD);
			client = cmdCtx.getModelControllerClient();
			if (cmdCtx.getExitCode() == 0 && !cmdCtx.isTerminated()) {
				int a = 1;
				for(int i=0;i<file4Dep.size();i++) {
					String fileName = file4Dep.get(i);
					baos = new ByteArrayOutputStream();
					repo.getFile(fileName, exeVer, new SVNProperties(), baos);
					ins = new ByteArrayInputStream( baos.toByteArray() );
					fn = new File(fileName);
					outputStream = new FileOutputStream(fn);
			 
					int read = 0;
					byte[] bytes = new byte[1024];
			 
					while ((read = ins.read(bytes)) != -1) {
						outputStream.write(bytes, 0, read);
					}
					
					String undeployCommand = "undeploy " + fileName + " --all-relevant-server-groups";
					requestNode = cmdCtx.buildRequest(undeployCommand);
					result = client.execute(requestNode);
					res = result.get("outcome").toString().substring(1, result.get("outcome").toString().length()-1);
					
					String isSuccess = "success".equalsIgnoreCase(res)?"t":"f";
					sql = "INSERT INTO depmemphisdetail (depMemphisSN,depMemphisDetailId,squadId,fileName,fileVer,relativePath,isSuccess,errMsg,isAssume,isDep) VALUES (?,?,?,?,?,?,?,?,?,?)";
					//表示目前還未創建，開始創建
					ps = conn.prepareStatement(sql);
					ps.setInt(1, depMemphisSN);
					ps.setInt(2, a++ );
					ps.setString(3,squadId);
					ps.setString(4,fileName);
					ps.setLong(5,exeVer);
					ps.setString(6,fileName);
					ps.setString(7,isSuccess);
					ps.setString(8,result.toString().replaceAll("\"", "~"));
					ps.setString(9,"f");	//是否為理論值
					ps.setString(10,"f");	//是否為部署
					ps.execute();
					if ( ps !=null ) {ps.close();}
					
					String deployCommand = "deploy " + fileName + " --server-groups=" + squadId;
					requestNode = cmdCtx.buildRequest(deployCommand);
					result = client.execute(requestNode);
					res = result.get("outcome").toString().substring(1, result.get("outcome").toString().length()-1);

					isSuccess = "success".equalsIgnoreCase(res)?"t":"f";
					//表示目前還未創建，開始創建
					ps = conn.prepareStatement(sql);
					ps.setInt(1, depMemphisSN);
					ps.setInt(2, a++ );
					ps.setString(3,squadId);
					ps.setString(4,fileName);
					ps.setLong(5,exeVer);
					ps.setString(6,fileName);
					ps.setString(7,isSuccess);
					ps.setString(8,result.toString());
					ps.setString(9,"f");	//是否為理論值
					ps.setString(10,"t");	//是否為部署
					ps.execute();
					
					
					if (ins != null) {ins.close();}
					if (outputStream != null) {outputStream.close();}
					if (fn != null) {if(fn.exists()){ fn.delete(); }}
					//開始更新待辦事項
					//刪除已完成的待辦事項，將其加入待辦清單
				}
			}
			int toDoListId = Integer.parseInt( request.getParameter("toDoListId") );	//待辦事項的號碼
			Widgets.completedList(toDoListId, empId);
			
			//開始寄發通知信
			List<String[]> tos = Widgets.getRecipient( MailType.DEPLOY2QA_SUCCESS,RecipientType.TO,subsysId);
			List<String[]> ccs = Widgets.getRecipient( MailType.DEPLOY2QA_SUCCESS,RecipientType.CC,subsysId);
			List<String[]> bccs = Widgets.getRecipient( MailType.DEPLOY2QA_SUCCESS,RecipientType.BCC,subsysId);
			String subject = subsysDesc+"-部署QA環境成功-"+chkInId;
			Widgets.sendMailMain(tos,ccs,bccs,subject, msgBody);
		} catch (Exception e) {
			Widgets.errLog(e);
			
			//部署失敗，寄發通知信
		} finally {
			try {
				if ( rs !=null ) { rs.close(); }
				if ( ps !=null ) { ps.close(); }
				if ( conn !=null ) { conn.close(); }
			} catch (SQLException e) { e.printStackTrace(); }
			if (repo != null) { repo.closeSession();}
			if (cmdCtx != null) {cmdCtx.terminateSession();}
			if (baos != null) {baos.close();}
			if (ins != null) {ins.close();}
			if (outputStream != null) {outputStream.close();}
		}

		response.getWriter().write(res);
	}

}
